home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / fe1.zip / BMP.CPP next >
C/C++ Source or Header  |  1992-02-07  |  18KB  |  700 lines

  1. #include <math.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4.  
  5. #include "bmp.h"
  6.  
  7. const char editmap :: mode_s = 'S' ;
  8. const char editmap :: mode_x = 'X' ;
  9. const char *editmap :: mode_str = "MODE:%c" ;
  10.  
  11. editmap :: editmap ( int wd, int hg, char *fn ) :
  12. win( 0, 0, fg.displaybox[FG_X2], fg.displaybox[FG_Y2], FG_WHITE,
  13.     FG_BLACK, NULL, 19, 2 ), w( wd ), h( hg ), draw_func( draw_pixel ),
  14.     filename( fn ), clipb( NULL )
  15. {
  16. #define MOSTLENGTH    13
  17. #define MOSTLENGTHP1    14
  18. #define MOSTLENGTHP2    15
  19.  
  20.     int i ;
  21.     fg_coord_t k ;
  22.  
  23.     bits = alloc_array( w, h ) ;
  24.     mode = new char [MOSTLENGTH] ;
  25.     func = new char [MOSTLENGTH] ;
  26.  
  27.     sprintf( mode, mode_str, mode_s ) ;
  28.  
  29.     for ( i = 0 ; i < w ; i++ )
  30.         memset( bits[i], 0, h ) ;
  31.  
  32.     cellbox[FG_X1] = cellbox[FG_Y1] = 0 ;
  33.     cellbox[FG_X2] =
  34.         ( fg.displaybox[FG_X2] -
  35.             fg.charbox[FG_X2] * MOSTLENGTHP2 ) / w ;
  36.     cellbox[FG_Y2] = ( fg.displaybox[FG_Y2] - fg.charbox[FG_Y2] * 2 ) / h ;
  37.  
  38.     fg_make_box( pix, -1, -1, -1, -1 ) ;
  39.     fg_make_box( editbox, 0, 0, cellbox[FG_X2] * w, cellbox[FG_Y2] * h );
  40.     editbox[FG_X1] += fg.charbox[FG_X2] ;
  41.     editbox[FG_X2] += fg.charbox[FG_X2] ;
  42.     editbox[FG_Y1] += fg.charbox[FG_Y2] ;
  43.     editbox[FG_Y2] += fg.charbox[FG_Y2] ;
  44.  
  45.     kbd->add_script( 'q', destroy ) ;
  46.     kbd->add_script( 'l', _set_draw_line ) ;
  47.     kbd->add_script( 'p', _set_draw_pixel ) ;
  48.     kbd->add_script( 'r', _redraw ) ;
  49.     kbd->add_script( 'f', _set_floodfill ) ;
  50.     kbd->add_script( 'c', _set_draw_circle ) ;
  51.     kbd->add_script( 'e', _set_draw_ellipse ) ;
  52.     kbd->add_script( 'b', _set_draw_box ) ;
  53.     kbd->add_script( 'm', set_mode ) ;
  54.     kbd->add_script( 'i', _set_invert_box ) ;
  55.     kbd->add_script( 'a', _set_clear ) ;
  56.     kbd->add_script( 'y', _set_copy ) ;
  57.     kbd->add_script( 'u', _set_cut ) ;
  58.     kbd->add_script( 'z', _set_paste ) ;
  59.     kbd->add_script( 'x', byebye ) ;
  60.     kbd->add_script( 's', save ) ;
  61.     kbd->add_script( ',', _set_flip_x ) ;
  62.     kbd->add_script( '.', _set_flip_y ) ;
  63.     kbd->add_script( '\x1b', finish_func ) ;
  64.     box->add_script( editbox, edit_map ) ;
  65.     box->add_script( winbox, total_map ) ;
  66.     k = fg.displaybox[FG_X2] - fg.charbox[FG_X2] * MOSTLENGTH ;
  67.     fg_make_box( dispbox, k, fg.charbox[FG_Y2], k + w - 1,
  68.         fg.charbox[FG_Y2] + h - 1 ) ;
  69. #define ITEMS    24
  70.     mu = new menu ( k, fg.displaybox[FG_Y2] - fg.charbox[FG_Y2] * ITEMS,
  71.         MOSTLENGTH -  2, ITEMS, this ) ;
  72.  
  73.     strcpy( func, "PIXEL" ) ;
  74.     mu->add_item( '\x0', "[P]ixel", _set_draw_pixel ) ;
  75.     mu->add_item( '\x0', "[L]ine", _set_draw_line ) ;
  76.     mu->add_item( '\x0', "[B]ox", _set_draw_box ) ;
  77.     mu->add_item( '\x0', "[C]ircle", _set_draw_circle ) ;
  78.     mu->add_item( '\x0', "[E]llipse", _set_draw_ellipse ) ;
  79.     mu->add_item( '\x0', "[F]ill", _set_floodfill ) ;
  80.     mu->add_item( '\x0', "[I]nvert", _set_invert_box ) ;
  81.     mu->add_item( '\x0', "--------", NULL ) ;
  82.     mu->add_item( '\x0', "Cop[Y]", _set_copy ) ;
  83.     mu->add_item( '\x0', "C[U]t", _set_cut ) ;
  84.     mu->add_item( '\x0', "Paste[Z]", _set_paste ) ;
  85.     mu->add_item( '\x0', "Cle[A]r", _set_clear ) ;
  86.     mu->add_item( '\x0', "--------", NULL ) ;
  87.     mu->add_item( '\x0', "[M]ode", set_mode ) ;
  88.     mu->add_item( '\x0', "[R]edraw", _redraw ) ;
  89.     mu->add_item( '\x0', "FlipX[,]", _set_flip_x ) ;
  90.     mu->add_item( '\x0', "FlipY[.]", _set_flip_y ) ;
  91.     mu->add_item( '\x0', "--------", NULL ) ;
  92.     mu->add_item( '\x0', "[S]ave", save ) ;
  93.     mu->add_item( '\x0', "[Q]uit", destroy ) ;
  94.     mu->add_item( '\x0', "e[X]it", byebye ) ;
  95.     mu->add_item( '\x0', "--------", NULL ) ;    
  96.     mu->add_item( '\x0', func, NULL ) ;
  97.     mu->add_item( '\x0', mode, NULL ) ;
  98. }
  99.  
  100. void editmap :: delete_array ( char **a, int w ) {
  101.  
  102.     if ( a ) {
  103.         for ( int i = 0 ; i < w ; i++ )
  104.             delete a[i] ;
  105.         delete a ;
  106.     }
  107. }
  108.  
  109. char **editmap :: alloc_array ( int w, int h ) {
  110.  
  111.     char **x ;
  112.  
  113.     x = new char * [w] ;
  114.     for ( int i = 0 ; i < w ; i++ )
  115.         x[i] = new char [h] ;
  116.     return x ;
  117. }
  118.  
  119. void editmap :: realloc_array ( char ***x, int w, int h ) {
  120.  
  121.     if ( x )
  122.         delete_array( *x, w ) ;
  123.     *x = alloc_array( w, h ) ;
  124. }
  125.  
  126. editmap :: ~editmap () {
  127.  
  128.     int i ;
  129.  
  130.     delete_array( bits, w ) ;
  131.     delete_array( clipb, clip_w ) ;
  132.     delete mode ;
  133. }
  134.  
  135. void editmap :: byebye () { save() ; destroy() ; }
  136.  
  137. void editmap :: copymap ( char **b ) {
  138.  
  139.     int i, j ;
  140.  
  141.     for ( i = 0 ; i < w ; i++ )
  142.         for ( j = 0 ; j < h ; j++ )
  143.             bits[i][j] = b[i][j] ;
  144. }
  145.  
  146. void editmap :: save () {
  147.  
  148.     FILE *f ;
  149.     char *xn, *da ;
  150.     char *defna = "Untitled" ;
  151.     fg_box_t t ;
  152.     int i, j, k, m, kda, msk ;
  153.  
  154.     if ( ( f = fopen( xn = filename, "wt" ) ) == NULL )
  155.         if ( ( f = fopen( xn = defna, "wt" ) ) == NULL )
  156.             return ;
  157.     da = new char [w + 1] ;
  158.     fg_make_box( t, 0, 0, w - 1, h - 1 ) ;
  159.     fprintf( f, "fg_box_t %s_box = { 0, 0, %d, %d } ;\n", xn, w-1, h-1 ) ;
  160.     fprintf( f, "char %s_matrix[%u] = {\n", xn, fg_matrix_size( t ) ) ;
  161.  
  162.     for ( i = 0 ; i < h ; i++ ) {
  163.         fprintf( f, "\t" ) ;
  164.         for ( j = 0 ; j < w ; j++ )
  165.             da[j] = bits[j][h - i - 1] ? '#' : ' ' ;
  166.         da[j] = 0 ;
  167.         for ( k = 0 ; k < w ; k += 8 ) {
  168.             msk = 0x80 ;
  169.             for ( kda = 0, m = k ; m < k + 8 && m < w ; m++ ) {
  170.                 if ( bits[m][h - i - 1] )
  171.                     kda |= msk ;
  172.                 msk >>= 1 ;
  173.             }
  174.             fprintf(
  175.                 f, "0x%02x%c ",
  176.                 kda, k + 8 < w || i + 1 < h ? ',' : ' ' ) ;
  177.         }
  178.         fprintf( f,"\t/* %s */\n", da ) ;
  179.     }
  180.     fprintf( f, "} ;\n" ) ;
  181.     fclose( f ) ;
  182.     delete da ;
  183. }        
  184.  
  185. fg_color_t editmap :: get_color () {
  186.     return p_status == MSM_BUTTONL ? fgc : bgc ;
  187. }
  188.  
  189. int editmap :: get_mode () {
  190.     return mode[strlen(mode)-1] == mode_s ? FG_MODE_SET : FG_MODE_XOR ;
  191. }
  192.  
  193. void editmap :: set_mode () {
  194.  
  195.     if ( get_mode() == FG_MODE_SET )
  196.         sprintf( mode, mode_str, mode_x ) ;
  197.     else
  198.         sprintf( mode, mode_str, mode_s ) ;
  199.     mu->expose() ;
  200. }
  201.  
  202. void editmap :: getmspos () {
  203.  
  204.     p_status = msm_getstatus( &p_x, &p_y ) ;
  205.     p_y = fg.displaybox[FG_Y2] + 1 - p_y ;    
  206. }
  207.  
  208. void editmap :: translate () {
  209.  
  210.     p_x = ( p_x - editbox[FG_X1] ) / cellbox[FG_X2] ;
  211.     p_y = ( p_y - editbox[FG_Y1] ) / cellbox[FG_Y2] ;
  212. }
  213.  
  214. void editmap :: set_funcname ( eventscript_t e, char *n ) {
  215.  
  216.     draw_func = e ;
  217.     finish_func() ;
  218.     strcpy( func, n ) ;
  219.     mu->expose() ;
  220. }
  221.  
  222. void editmap :: _set_floodfill () { set_funcname( floodfill, "FILL" ) ; }
  223.  
  224. void editmap :: floodfill () {
  225.  
  226.     if ( pix[FG_X1] == -1 ) {
  227.         msm_hidecursor() ;
  228.         fg_fill( dispbox[FG_X1] + p_x, dispbox[FG_Y1] + p_y,
  229.             get_color(), get_color() ) ;
  230.         msm_showcursor() ;
  231.         redraw( 0, 0, w - 1, h - 1 ) ;
  232.         finish_func() ;
  233.     }
  234. }
  235.  
  236. void editmap :: _set_draw_line () { set_funcname( draw_line, "LINE" ) ; }
  237.  
  238. void editmap :: draw_line () {
  239.  
  240.     fg_coord_t x1, y1, x2, y2 ;
  241.  
  242.     if ( pix[FG_X1] == -1 ) {
  243.         pix[FG_X1] = p_x ;
  244.         pix[FG_Y1] = p_y ;
  245.     } else if ( pix[FG_X2] == -1 ) {
  246.         x1 = min( p_x, pix[FG_X1] ) ;
  247.         x2 = max( p_x, pix[FG_X1] ) ;
  248.         y1 = min( p_y, pix[FG_Y1] ) ;
  249.         y2 = max( p_y, pix[FG_Y1] ) ;
  250.         pix[FG_X2] = p_x ;
  251.         pix[FG_Y2] = p_y ;
  252.         pix[FG_X1] += dispbox[FG_X1] ;
  253.         pix[FG_X2] += dispbox[FG_X1] ;
  254.         pix[FG_Y1] += dispbox[FG_Y1] ;
  255.         pix[FG_Y2] += dispbox[FG_Y1] ;
  256.         msm_hidecursor() ;
  257.         fg_drawlineclip( get_color(), get_mode(), ~0, FG_LINE_SOLID,
  258.             pix, dispbox ) ;
  259.         msm_showcursor() ;
  260.         finish_func() ;
  261.         redraw( x1, y1, x2, y2 ) ;
  262.     }
  263. }
  264.  
  265. void editmap :: _set_draw_box () { set_funcname( draw_box, "BOX" ) ; }
  266.  
  267. void editmap :: draw_box () {
  268.  
  269.     fg_coord_t x1, y1, x2, y2 ;
  270.  
  271.     if ( pix[FG_X1] == -1 ) {
  272.         pix[FG_X1] = p_x ;
  273.         pix[FG_Y1] = p_y ;
  274.     } else if ( pix[FG_X2] == -1 ) {
  275.         x1 = min( p_x, pix[FG_X1] ) ;
  276.         x2 = max( p_x, pix[FG_X1] ) ;
  277.         y1 = min( p_y, pix[FG_Y1] ) ;
  278.         y2 = max( p_y, pix[FG_Y1] ) ;
  279.         pix[FG_X1] = dispbox[FG_X1] + x1 ;
  280.         pix[FG_X2] = dispbox[FG_X1] + x2 ;
  281.         pix[FG_Y1] = dispbox[FG_Y1] + y1 ;
  282.         pix[FG_Y2] = dispbox[FG_Y1] + y2 ;
  283.         msm_hidecursor() ;
  284.         fg_drawbox( get_color(), get_mode(), ~0, FG_LINE_SOLID,
  285.             pix, dispbox ) ;
  286.         msm_showcursor() ;
  287.         finish_func() ;
  288.         redraw( x1, y1, x2, y2 ) ;
  289.     }
  290. }
  291.  
  292. void editmap :: _set_invert_box () { set_funcname( invert_box, "INVERT" ) ; }
  293.  
  294. void editmap :: invert_box () {
  295.  
  296.     fg_coord_t x1, y1, x2, y2 ;
  297.  
  298.     if ( pix[FG_X1] == -1 ) {
  299.         pix[FG_X1] = p_x ;
  300.         pix[FG_Y1] = p_y ;
  301.     } else if ( pix[FG_X2] == -1 ) {
  302.         x1 = min( p_x, pix[FG_X1] ) ;
  303.         x2 = max( p_x, pix[FG_X1] ) ;
  304.         y1 = min( p_y, pix[FG_